[转]OpenStack extension api

原作者:张华
原文链接

openstack的扩展API有两类:
1) resource extension, 可参见:$nova/nova/api/openstack/compute/contrib/server_password.py, 需实现get_resource方法,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def get_resources(self):
member_actions = {'action': 'POST'}
collection_actions = {'add': 'POST'}
res = extensions.ResourceExtension(
'os-networks',
NetworkController(),
member_actions=member_actions,
collection_actions=collection_actions)
return [res]
    会产生如下格式的REST URL:
GET /os-networks
POST /os-networks
POST /os-networks/add
PUT /os-networks/id
DELETE /os-networks/id
GET /os-networks/id
POST /os-networks/id/action

2) controller extension, 可参见:$nova/nova/api/openstack/compute/contrib/server_password.py, 需实现get_controller_extensions方法,如:

1
2
3
4
def get_controller_extensions(self):
 controller = Controller(self.ext_mgr)
 extension = extensions.ControllerExtension(self, 'servers', controller)
 return [extension]

  但是,如果不是新建,而是想扩展已存在的resource extension和extroller extension呢,如下的例子:
  1)加@wsgi.extends(action=’resize’)修饰符即可
  2)记得加yield,让它成为一个生成器,这样就会先执行我们自己扩展的extension api,然后再去执行原有的api,相当于继承吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Server_resource(extensions.ExtensionDescriptor):
"""Start/Stop instance compute API support."""
name = "ServerResource"
alias = "os-server-resource"
namespace = "http://docs.openstack.org/compute/ext/server-resource/api/v1.1"
updated = "2013-01-13T00:00:00+00:00"
def get_controller_extensions(self):
controller = ServerController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
class ServerController(wsgi.Controller):
def __init__(self):
print 'init'
@wsgi.extends
def create(self, req, body):
print 'update'
    yield
@wsgi.extends(action='resize')
def _action_resize(self, req, id, body):
print 'resize'
yield

因为上面是一个生成器,可以这样调用:
[python]self.controller.create(req, body).next()[/python]
或者用for循环调用。另外在单元测试时使用assertRaises时调用它时传给Mock的应该是一个函数地址,所以下面的调用在next后面不要加括号哦。
[python]self.assertRaises(exc.HTTPBadRequest, self.controller.create(req, body).next)[/python]

测试:

1
2
3
4
5
TOKEN=`curl -s -d "{\"auth\":{\"passwordCredentials\":{\"username\": \"$OS_USERNAME\", \"password\":\"$OS_PASSWORD\"}, \"tenantName\":\"$OS_TENANT_NAME\"}}" -H "Content-type:application/json" $OS_AUTH_URL/tokens | python -c"import sys; import json; tok = json.loads(sys.stdin.read()); print tok['access']['token']['id'];"`
curl -i -X POST -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN" -d '{"server": {"flavorRef": "http://openstack.example.com/openstack/flavors/1","imageRef": "http://openstack.example.com/openstack/images/e0ba6d0a-c705-4dbd-bd3b-b35bbbb8f8a5","name":"i1","ram":"1024","vcpus":"1","disk":"10"}}' http://192.168.0.1:8774/v2/5685706e11ff4e9fb4ffdfac7ed2fb6e/servers
curl -i -X POST -H "Content-Type: application/json" -H "X-Auth-Token:$TOKEN" -d '{"resize" : {"flavorRef" : "2","ram":"1024","vcpus":"1","disk":"10"}}' http://192.168.0.1:8774/v2/5685706e11ff4e9fb4ffdfac7ed2fb6e/servers/ec95e413-f033-4f02-a9c4-b16fe7d398cd/action

Jerky Lu wechat
欢迎加入微信公众号